/**
 * 浅拷贝
 * 1.创建一个新的对象，来接受你要重新复制或引用的对象值。
 * 2.基本的数据类型，复制基本类型的值给新对象；
 * 3.属性是引用数据类型，复制的就是内存中的地址
 * 4.如果其中一个对象改变了这个内存中的地址，肯定会影响到另一个对象。
 */

/**
 * 方法一：object.assign
 * 第一个参数是拷贝的目标对象，后面的参数是拷贝的来源对象（也可以是多个来源）。
 * Object.assign(target, ...sources)
 * Object.assign 循环遍历原对象的属性，通过复制的方式将其赋值给目标对象的相应属性
 *    它不会拷贝对象的继承属性；
 *    它不会拷贝对象的不可枚举的属性；
 *    可以拷贝 Symbol 类型的属性
 */


/**
 * 方法二：拓展运算符
 * let cloneObj = { ...obj };
 * 缺点同上
 */

/**
 * 方法三：concat 拷贝数组也是浅拷贝
 * 连接一个含有引用类型的数组时，需要注意修改原数组中的元素的属性
 * 只能用于数组
 * newArr = arr.concat();
 */

/**
 * 方法四：slice 拷贝数组
 * 针对数组类型
 * 前两个参数来决定原数组截取的开始和结束时间，
 * 是不会影响和改变原始数组的
 */

/**
 * 方法五：手动实现浅拷贝
 * 1.对基础类型做一个最基本的一个拷贝；
 * 2.对引用类型开辟一个新的存储cloneTarget，并且拷贝一层对象属性。
 */
function shallowClone(source) {
  if (typeof source === 'object' && typeof source !== null) {
    //source是除function以外的对象
    const cloneTarget = Array.isArray(source) ? [] : {}
    for (let prop in source) {
      //prop是下标/key，source[prop]是每一个元素
      if (source.hasOwnProperty(prop)){
        // 这个是只复制实例属性，不复制继承的属性
        cloneTarget[prop] = source[prop]
      }
    }
    return cloneTarget
  }else{
    return source
  }
}

let target = []
let source = { a: { b: 1 } }
target = shallowClone(source)
source.a.b = 5
console.log(target);